import React, {FC, useCallback, useEffect, useMemo, useRef, useState} from "react";
import {useTranslation} from "react-i18next";
import SelectTransfer from "../../../module/dataForm/SelectTransfer.tsx";
import {AxiosGet, AxiosSer} from "../../../services/HttpService.tsx";
import {addOkModal, closeModal} from "../../../services/ModalService.tsx";
import useThrottle from "../../../customUse/useThrottle.tsx";
import {Spin} from "antd";
import useStateRef from "../../../customUse/useStateRef.tsx";
import {createParams, getObjByRule} from "../../../utils";

interface AddOrganizationModalProps {
    modalKey?: string,
    flowData: any[],
    url: string,
    getUrl: string,
    getParams?: any,
    method: string,
    transferField?: string[],
}

const AddOrganizationModal: FC<AddOrganizationModalProps> = (props) => {
    const {t} = useTranslation();
    const {transferField = ["alternativeRoles", "containRoles"]} = props
    const oldSelectKeysRef = useRef(""),
        selectKeysRef = useRef(""),
        selectInfoRef = useRef({});

    const [loading, setLoading] = useState(false),
        [selectInfo, setSelectInfo] = useStateRef({}, selectInfoRef),
        [dataSource, setDataSource] = useState(undefined);

    const loadData = useCallback(async () => {
        let {flowData, getUrl, getParams = {}} = props;
        let info = flowData ? {...flowData[0]} : {};
        const params = getObjByRule(info, getParams);
        setLoading(true);
        let {data = {}} = await AxiosGet(getUrl, params);
        const leftData = data[transferField[0]];
        const rightData = data[transferField[1]];
        setLoading(false);
        selectKeysRef.current = rightData.map(i => i.id).join(",")
        oldSelectKeysRef.current = rightData.map(i => i.id).join(",")
        setDataSource([...leftData, ...rightData])
        setSelectInfo(info)
    }, [])

    useEffect(() => {
        loadData();
    }, []);

    const compareIds = useCallback((newIds, oldIds) => {
        const newIdList = newIds.split(',');
        const oldIdList = oldIds.split(',');

        const newIdSet = new Set(newIdList);
        const oldIdSet = new Set(oldIdList);

        const addIds = newIdList.filter(id => !oldIdSet.has(id));

        const removeIds = oldIdList.filter(id => !newIdSet.has(id));

        return {
            addIds,
            removeIds
        };
    }, [])

    const isEdit: Function = useCallback(() => {
        return props.type === "edit";
    }, [props.type]);

    const onOk = useThrottle(async () => {
        const {url, method} = props;
        const params = compareIds(selectKeysRef.current, oldSelectKeysRef.current);
        const newParams = createParams(params, props);
        const methodType = method ? method : (isEdit() ? "PUT" : "POST");
        setLoading(true);
        const result = await AxiosSer(url, methodType, {
            ...newParams
        }, true) || {};
        setLoading(false);
        result.code == "1" && await closeModal(props.modalKey, async () => {
            return {data: newParams, ...result};
        });
    }, 2000, [props.url]);

    useEffect(() => {
        addOkModal(props.modalKey, onOk);
    }, []);

    const handleChange = useCallback((selectKeys) => {
        selectKeysRef.current = selectKeys
    }, [])

    const renderAddOrganizationModal = useMemo(() => {
        return (
            <Spin spinning={loading} className="sf_core_add_role">
                <div className="sf_core_add_role_title">
                    {t("name")}: {selectInfo.name}
                </div>
                <div className="sf_core_add_role_transfer">
                    <SelectTransfer
                        width={400}
                        height={400}
                        transferField={transferField}
                        dataSource={dataSource}
                        value={oldSelectKeysRef.current}
                        format={{
                            key: "id",
                            label: "name"
                        }}
                        onChange={handleChange}
                    />
                </div>
            </Spin>
        )
    }, [selectInfo, dataSource, loading]);

    return (renderAddOrganizationModal);
};

export default React.memo(AddOrganizationModal);